package com.zhidian.edm.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zhidian.edm.entity.SysTokenPO;
import com.zhidian.edm.entity.SysUserPO;
import com.zhidian.edm.param.LoginRequestParam;
import com.zhidian.edm.result.ResultResponse;
import com.zhidian.edm.service.ISysTokenService;
import com.zhidian.edm.service.ISysUserService;
import com.zhidian.edm.util.JwtUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.Optional;

@RestController
@Tag(name = "登录登出模块", description = "登录登出模块")
public class LoginController {

    @Resource
    private  JwtUtil jwtUtil;
    @Resource
    private  ISysTokenService tokenService;
    @Resource
    private  ISysUserService userService;
    @Resource
    private  PasswordEncoder passwordEncoder;


    @PostMapping("/login")
    @Operation(summary = "登录接口", description = "登录接口")
    @Transactional(rollbackFor = Exception.class)
    public ResultResponse<Map<String, String>> login(@RequestBody LoginRequestParam req) {
        Optional<SysUserPO> userOpt = userService.findByUsername(req.getUserName());
        if (userOpt.isEmpty()) {
            return ResultResponse.fail("用户名或密码错误");
        }
        SysUserPO user = userOpt.get();

        if (!passwordEncoder.matches(req.getPassword(), user.getPassword())) {
            return ResultResponse.fail("用户名或密码错误");
        }

        // 生成 JWT
        String token = jwtUtil.generateToken(user.getId(), user.getUserName());

        // 吊销旧 Token 踢人
        tokenService.remove(new LambdaQueryWrapper<>(SysTokenPO.class).eq(SysTokenPO::getUserId, user.getId()));
        // 保存 token 到数据库
        LocalDateTime expAt = LocalDateTime.now().plusMinutes(60); // 和 jwt expire 一致
        SysTokenPO sysToken = new SysTokenPO();
        sysToken.setUserId(user.getId());
        sysToken.setToken(token);
        sysToken.setExpiredTime(expAt);
        tokenService.save(sysToken);

        return ResultResponse.success(Map.of(
                "token", token,
                "username", user.getUserName(),
                "expiresTime", expAt.toString()
        ));
    }

    @GetMapping("/logout")
    @Operation(summary = "登出接口", description = "登出接口")
    public ResultResponse<Void> logout(HttpServletRequest req) {
        String token = req.getHeader("Authorization");
        if (token != null) {
            Long userId = jwtUtil.getUserId(token);
            tokenService.remove(new LambdaQueryWrapper<>(SysTokenPO.class).eq(SysTokenPO::getUserId, userId));
        }
        SecurityContextHolder.clearContext();
        return ResultResponse.success();
    }

}
